package maggames.core;

import java.util.ArrayList;
import java.util.Iterator;

import maggames.core.exceptions.InvalidTurnException;

/**
 * Object comprised of a series of game moves which will be evaluated as a single
 * player's turn.  Several utility methods are present to aid in the duplication and
 * management of turn objects to ensure that common moves are not a problem.
 * 
 * @author BenjaminPLee
 * @version 2.0
 */
public class GameTurn {
	private ArrayList<GameMove> moves;
	private Player mover;
	private ArrayList<InvalidTurnException> problems;
	
	/**
	 * Default constructor, initializes move container
	 */
	public GameTurn(Player mover) {
		moves = new ArrayList<GameMove>();
		problems = new ArrayList<InvalidTurnException>();
		this.mover = mover;
	}
	
	/**
	 * Copy constructor.  Creates new turn object with same values as given one.
	 * 
	 * @param turn turn to be copied
	 */
	public GameTurn(GameTurn turn) {
		this.moves = turn.getMovesCopy();
		this.mover = turn.getMover();
	}
	
	/**
	 * Utility constructor builds a new turn object initialized with the given move
	 * 
	 * @param move
	 */
	public GameTurn(GameMove move, Player mover) {
		moves = new ArrayList<GameMove>();
		moves.add(move);
		
		this.mover = mover;
	}
	
	/**
	 * Adds the given move to the list of moves in the turn
	 * 
	 * @param move new move object
	 */
	public void addMove(GameMove move) {
		moves.add(move);
	}
	
	/**
	 * Adds all moves found in the given turn to the called turn objects (copies)
	 * 
	 * @param turn turn containing the moves to be added
	 */
	public void addTurn(GameTurn turn) {
		ArrayList <GameMove> newMoves = turn.getMovesCopy();
		moves.addAll(newMoves);
	}
	
	/**
	 * Returns the move at the given list index position
	 * 
	 * @param index
	 * @return GameMove at the given index
	 */
	public GameMove getMove(int index) {
		return (GameMove)moves.get(index);
	}
	
	/**
	 * Removes the move at the given index from the turn
	 * 
	 * @param index
	 */
	public void removeMove(int index) {
		moves.remove(index);
	}
	
	/**
	 * Returns the number of moves present in the turn
	 * 
	 * @return number of moves in the given turn
	 */
	public int getNumMoves() {
		return moves.size();
	}
	
	/**
	 * Returns an interator to the moves list
	 * 
	 * @return iterator over the turn's moves
	 */
	public Iterator <GameMove> getMovesIterator() {
		return moves.iterator();
	}
	
	/**
	 * Returns a new copy of all the the turn's moves
	 * 
	 * @return List containing a new copy of the turn's moves
	 */
	public ArrayList<GameMove> getMovesCopy() {
		ArrayList<GameMove> newMoves = new ArrayList<GameMove>();
		
		Iterator <GameMove> i = moves.iterator();
		while(i.hasNext()) {
			GameMove newMove = new GameMove(i.next());
			newMoves.add(newMove);
		}
		
		return newMoves;
	}
	
	/**
	 * @return the mover
	 */
	public Player getMover() {
		return mover;
	}

	/**
	 * @param mover the mover to set
	 */
	public void setMover(Player mover) {
		this.mover = mover;
	}
	
	/**
	 * @return the last move made
	 */
	public GameMove getLastMove() {
		if(this.moves.size()>0) {
			return this.getMove(this.getNumMoves()-1);
		}
		else {
			return null;
		}
	}
	
	/**
	 * Removes the last move made
	 */
	public void removeLastMove() {
		if(this.moves.size()>0) {
			this.moves.remove(this.getNumMoves()-1);
		}
	}

	/**
	 * @return the problems
	 */
	public ArrayList<InvalidTurnException> getProblems() {
		return problems;
	}
	
	public void addProblem(InvalidTurnException problem) {
		this.problems.add(problem);
	}
	
	// TODO write equals method and hashmap?	
}